
//
//  FUtil.m
//  ui
//
//  Created by 袁飞 on 12-7-14.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "FUtil.h"
#import "TBXML.h"
#import "regex.h"
@implementation FUtil
+(CGPoint)string2Point:(NSString*)str{
  NSRange nr = [str rangeOfString:@","];
  int pos = nr.location;
  NSString *s1 = [str substringToIndex:pos];
  NSString *s2 = [str substringFromIndex:pos+1];
  return ccp([s1 floatValue], [s2 floatValue]);
}

+(CGSize)string2Size:(NSString*)str{
  CGPoint p = [FUtil string2Point:str];
  return CGSizeMake(p.x, p.y);
}

+(bool)RegExpMatch:(NSString *)string withPattern:(NSString*)pattern{
  regex_t reg;
  regmatch_t sub[10];
  int status=regcomp(&reg, [pattern UTF8String], REG_EXTENDED);
  if(status)return NO;
  status=regexec(&reg, [string UTF8String], 10, sub, 0);
  if(status==REG_NOMATCH)return NO;
  else if(status)return NO;
  return YES;
}

+(NSMutableArray*)splitStr:(NSString*)src byFlag:(NSString*)f{
  int p = 0;
  //NSLog(@"%@ %d", mstr, mstr.length);
  NSMutableArray *array = [NSMutableArray array];
  for(; p<src.length;){
    NSRange limit;
    limit.location = p;
    limit.length = src.length-p;
    NSRange res1 = [src rangeOfString:f options:1 range:limit];
    //NSLog(@"res1 %d %d", res1.location, res1.length);
    if(res1.length == 0){
      //NSLog(@"break res1 %d %d", res1.location, res1.length);
      NSString* tmp = [src substringWithRange:NSMakeRange(p, src.length-p)];
      [array addObject:tmp];
      break;
    }
    NSString* tmp = [src substringWithRange:NSMakeRange(p, res1.location-p)];
    p = res1.location + f.length;
    [array addObject:tmp];
  }
  return array;
}

+(NSMutableArray*)getFramesNamed:(NSString*)name FromPlist:(NSString*)plname{
  NSMutableArray * arr = [NSMutableArray array];
  NSString* fullfilename = [[CCFileUtils sharedFileUtils] fullPathFromRelativePath:plname];
  NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:fullfilename];
  NSMutableDictionary *frames = [dict objectForKey:@"frames"];
  for(NSObject* o in frames){
    NSString* ns = o;
    if ([FUtil RegExpMatch:ns withPattern:name]) {
      [arr addObject:ns];
    }
  }
  //NSLog(@"%@", arr);
  NSSortDescriptor* sortByA = [NSSortDescriptor sortDescriptorWithKey:@"" ascending:YES];
  [arr sortUsingDescriptors:[NSArray arrayWithObject:sortByA]];
  //NSLog(@"%@", arr);
  sortByA = [NSSortDescriptor sortDescriptorWithKey:@"length" ascending:YES];
  [arr sortUsingDescriptors:[NSArray arrayWithObject:sortByA]];
  //NSLog(@"%@", arr);
  //sortDescriptor = [[NSSortDescriptor] alloc] initW
  return arr;
}

+(CGPoint)actualPoint:(CGPoint)pos Size:(CGSize)s{
  float x, y;
  if ((pos.x>0 && pos.x<1) || (pos.x>-1 && pos.x<0)) {
    x = s.width * pos.x;
  }
  if ((pos.y>0 && pos.y<1) || (pos.y>-1 && pos.y<0)) {
    y = s.height * pos.y;
  }
  return ccp(x, y);
}

+(CGSize)getSize:(TBXMLElement*)element{
  TBXMLElement* te = [TBXML childElementNamed:@"size" parentElement:element];
  if (te == nil) {
    return CGSizeMake(0, 0);
  }
  NSString * ss = [TBXML textForElement:te];
  return [FUtil string2Size:ss];
}

+(CGPoint)getPosition:(TBXMLElement*)element{
  TBXMLElement* te = [TBXML childElementNamed:@"position" parentElement:element];
  if (te == nil) {
    return ccp(0, 0);
  }
  NSString* value = [TBXML textForElement:te];
  return [FUtil string2Point:value];
}

+(NSString*)getName:(TBXMLElement*)element{
  TBXMLElement* te = [TBXML childElementNamed:@"name" parentElement:element];
  if (te == nil) {
    return @"";
  }
  return [TBXML textForElement:te];
}

+(NSString*)getImg:(TBXMLElement*)element{
  TBXMLElement* te = [TBXML childElementNamed:@"img" parentElement:element];
  if (te == nil) {
    return @"";
  }
  return [TBXML textForElement:te];
}
+(int)getZ:(TBXMLElement*)element{
  TBXMLElement* te = [TBXML childElementNamed:@"z" parentElement:element];
  if (te == nil) {
    return 0;
  }
  NSString* value = [TBXML textForElement:te];
  return [value intValue];
}

+(float)getDur:(TBXMLElement*)element{
  TBXMLElement* te = [TBXML childElementNamed:@"dur" parentElement:element];
  if (te == nil) {
    return 0;
  }
  NSString* value = [TBXML textForElement:te];
  return [value floatValue];

}

+(CCAction*)actionWith:(NSString*)file  WithDict:(NSMutableDictionary*)dict{
  NSString *res = [FUtil expandFile:file WithDict:dict];
  TBXML *xml = [[TBXML alloc] initWithXMLString:res];
  if (!xml) {
    NSLog(@"load xml err %@", file);
  }
  TBXMLElement *root_element = [xml rootXMLElement];
  NSString *name = [FUtil getName:root_element];
  float dur = [FUtil getDur:root_element];
  NSMutableArray* frames = [NSMutableArray array];
  TBXMLElement *element = [TBXML childElementNamed:@"frame" parentElement:root_element];
  for (; element!=nil; ) {
    NSString* img = [TBXML textForElement:element];
    NSString* fn = [img substringToIndex:[img rangeOfString:@"_"].location];
    fn = [NSString stringWithFormat:@"%@_normal.plist",fn];
    NSMutableArray *fns = [FUtil getFramesNamed:img FromPlist:fn];
    for (NSString* o in fns) {
      CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:o];
      [frames addObject:frame];
    }
    element = [TBXML nextSiblingNamed:@"frame" searchFromElement:element];
  }
  CCAnimation *ani = [CCAnimation animationWithSpriteFrames:frames delay:dur/frames.count];
  CCActionInterval *action = [CCAnimate actionWithAnimation:ani]; //CCAnimate::actionWithAnimation(ani);
  return action;
}

+(FButton*)buttonFromXmlElement:(TBXMLElement*)element{
  TBXMLElement *root_element = element;  
  
  TBXMLElement* te = [TBXML childElementNamed:@"positon" parentElement:root_element];
  NSString* value = [TBXML textForElement:te];
  CGPoint positon = [FUtil string2Point:value];
  
  te = [TBXML childElementNamed:@"z" parentElement:root_element];
  value = [TBXML textForElement:te];
  int z = [value intValue];

  te = [TBXML childElementNamed:@"name" parentElement:root_element];
  NSString *name = [TBXML textForElement:te];
  
  NSString *normal, *highlight, *disabled;
  te = [TBXML childElementNamed:@"normal" parentElement:root_element];
  if (te) {
    normal = [TBXML textForElement:te];
  }else{
    return nil;
  }
  
  te = [TBXML childElementNamed:@"highlight" parentElement:root_element];
  if (te) {
    highlight = [TBXML textForElement:te];
  }else{
    highlight = normal;
  }
  
  te = [TBXML childElementNamed:@"disabled" parentElement:root_element];
  if (te) {
    disabled = [TBXML textForElement:te];
  }else{
    disabled = normal;
  }
  
  FButton *b = [FButton FButtonWithName:name Normal:normal Highlight:highlight Disabled:disabled Scaled:1.0f];
  [b setPosition:positon];
  [b setZOrder:z];
  return b;
}

+(FButton*)buttonFromXmlFile:(NSString*)file{
  return nil;
}

+(CCSprite*)spriteFromXmlElement:(TBXMLElement*)element{
  TBXMLElement *root_element = element;

  TBXMLElement* te = [TBXML childElementNamed:@"positon" parentElement:root_element];
  NSString* value = [TBXML textForElement:te];
  CGPoint positon = [FUtil string2Point:value];
  
  te = [TBXML childElementNamed:@"z" parentElement:root_element];
  value = [TBXML textForElement:te];
  int z = [value intValue];
  
  NSString *normal;
  te = [TBXML childElementNamed:@"img" parentElement:root_element];
  if (te) {
    normal = [TBXML textForElement:te];
  }else{
    return nil;
  }
  CCSprite* sp = [CCSprite spriteWithSpriteFrameName:normal];
  [sp setPosition:positon];
  [sp setZOrder:z];
  return sp;
}

+(CCLabelTTF*)labelFromXmlElement:(TBXMLElement*)element{
  TBXMLElement *root_element = element;
  TBXMLElement* te = [TBXML childElementNamed:@"positon" parentElement:root_element];
  NSString* value = [TBXML textForElement:te];
  CGPoint positon = [FUtil string2Point:value];

  te = [TBXML childElementNamed:@"z" parentElement:root_element];
  value = [TBXML textForElement:te];
  int z = [value intValue];
  
  te = [TBXML childElementNamed:@"text" parentElement:root_element];
  NSString* text = [TBXML textForElement:te];
  
  CCLabelTTF *label = [CCLabelTTF labelWithString:text fontName:@"Marker Felt" fontSize:15];
  [label setPosition:positon];
  [label setZOrder:z];
  [label setColor:ccc3(0, 255, 0)];
  return label;
}

+(CCLayer*)layerFromFile:(NSString*)file{

  //UITextFieldDelegate
  CCLayer *l = [[CCLayer alloc] init];
  
  TBXML *xml = [[TBXML alloc] initWithXMLFile:file];
  if (!xml) {
    NSLog(@"load xml err %s", file);
  }
  TBXMLElement *root_element = [xml rootXMLElement];
  TBXMLElement *element;

  element = [TBXML childElementNamed:@"size" parentElement:root_element];
  NSString * ss = [TBXML textForElement:element];
  CGSize s = [FUtil string2Size:ss];
  [l setContentSize:s];
  s = CGSizeMake(s.width, s.height-20);
  element = [TBXML childElementNamed:@"position" parentElement:root_element];
  NSString * sp = [TBXML textForElement:element];
  CGPoint p = [FUtil string2Point:sp];
  [l setPosition:p];
  
  NSMutableDictionary *pars = [NSMutableDictionary dictionary];
  element = [TBXML childElementNamed:@"par" parentElement:root_element];
  if (element) {
    element = element->firstChild;
    for (; element!=nil;) {
      NSString* name = [TBXML elementName:element];
      NSString* value = [TBXML textForElement:element];
      element = element->nextSibling;
      [pars setObject:name forKey:value];
    }
  }
  
  element = [TBXML childElementNamed:@"layer" parentElement:root_element];
  for (; element!=nil;) {
    TBXMLElement *te = [TBXML childElementNamed:@"file" parentElement:element];
    NSString *file = [TBXML textForElement:te];
    
    te = [TBXML childElementNamed:@"position" parentElement:element];
    NSString* value = [TBXML textForElement:te];
    CGPoint positon = [FUtil string2Point:value];
    CGPoint tp = [FUtil actualPoint:positon Size:s];
    
    CCLayer *tl = [FUtil layerFromFile:file];
    [tl setPosition:[FUtil actualPoint:positon Size:s]];
    [l addChild:tl];
    element = [TBXML nextSiblingNamed:@"layer" searchFromElement:element];
  }
  
  
  element = [TBXML childElementNamed:@"button" parentElement:root_element];
  for (; element!=nil;) {
    FButton *b = [FUtil buttonFromXmlElement:element];
    [l addChild:b];
    element = [TBXML nextSiblingNamed:@"button" searchFromElement:element];
  }
  
  element = [TBXML childElementNamed:@"sprite" parentElement:root_element];
  for (; element!=nil;) {
    CCSprite *sp = [FUtil spriteFromXmlElement:element];
    CGPoint pos = [sp position];
    [sp setPosition:[FUtil actualPoint:pos Size:s]];
    [l addChild:sp];
    element = [TBXML nextSiblingNamed:@"sprite" searchFromElement:element];
  }
  
  element = [TBXML childElementNamed:@"label" parentElement:root_element];
  for (; element!=nil;) {
    CCLabelTTF *label = [FUtil labelFromXmlElement:element];
    CGPoint pos = [label position];
    [label setPosition:[FUtil actualPoint:pos Size:s]];
    [l addChild:label];
    element = [TBXML nextSiblingNamed:@"label" searchFromElement:element];
  }
  
  return l;
}

+(NSString*)expandFile:(NSString*)file WithDict:(NSMutableDictionary*)dict{
  TBXML *xml = [[TBXML alloc] initWithXMLFile:file];
  if (!xml) {
    NSLog(@"load xml err %@", file);
  }
  TBXMLElement *root_element = [xml rootXMLElement];
  NSMutableDictionary* tmp = [FUtil getDictFromAttribute:root_element];
  if (dict != nil) {
    for(NSString* s in dict){
      [tmp setObject:[dict objectForKey:s] forKey:s];
    }
  }
  dict = tmp;
  [xml release];
  NSString* fullfilename = [[CCFileUtils sharedFileUtils] fullPathFromRelativePath:file];
  NSString *data = [NSString stringWithContentsOfFile:fullfilename encoding:NSUTF8StringEncoding error:nil];
  NSString *res = [FUtil expandStr:data WithDict:dict];
  return res;
}

+(CCLayer*)layerFromFile:(NSString*)file withDict:(NSMutableDictionary*)dict{
  CCLayer *l = [[[CCLayer alloc] init] autorelease];
  //NSLog(@"load xml %@", file);
  TBXML *xml = [[TBXML alloc] initWithXMLFile:file];
  if (!xml) {
    NSLog(@"load xml err %@", file);
  }
  TBXMLElement *root_element = [xml rootXMLElement];
  NSMutableDictionary* tmp = [FUtil getDictFromAttribute:root_element];
  if (dict != nil) {
    for(NSString* s in dict){
      [tmp setObject:[dict objectForKey:s] forKey:s];
    }
  }
  dict = tmp;
  [xml release];
  NSString* fullfilename = [[CCFileUtils sharedFileUtils] fullPathFromRelativePath:file];
  NSString *data = [NSString stringWithContentsOfFile:fullfilename encoding:NSUTF8StringEncoding error:nil];
  NSString *res = [FUtil expandStr:data WithDict:dict];
  
  xml = [[TBXML alloc] initWithXMLString:res error:nil];
  root_element = [xml rootXMLElement];
  
  TBXMLElement *element = [TBXML childElementNamed:@"size" parentElement:root_element];
  NSString * ss = [TBXML textForElement:element];
  CGSize s = [FUtil string2Size:ss];
  [l setContentSize:s];
  s = CGSizeMake(s.width, s.height-20);
  element = [TBXML childElementNamed:@"position" parentElement:root_element];
  NSString * sp = [TBXML textForElement:element];
  CGPoint p = [FUtil string2Point:sp];
  [l setPosition:p];

  
  element = root_element->firstChild;
  for(;element!=nil;){
    NSString *name = [TBXML elementName:element];
    //NSLog(@"node %@", name);
    if([name compare:@"layer"] == NSOrderedSame){
      NSMutableDictionary* td = [FUtil getDictFromAttribute:element];
      NSString* tpl = [td objectForKey:@"tpl"];
      //NSLog(@"tpl %@", name);
      CCLayer * tl = [self layerFromFile:tpl withDict:td];
      [l addChild:tl];
    }else if([name compare:@"sprite"] == NSOrderedSame){
      CCSprite *sp = [FUtil spriteFromXmlElement:element];
      CGPoint pos = [sp position];
      [sp setPosition:[FUtil actualPoint:pos Size:s]];
      [l addChild:sp];
    }else if([name compare:@"label"] == NSOrderedSame){
      CCSprite *sp = [FUtil labelFromXmlElement:element];
      CGPoint pos = [sp position];
      [sp setPosition:[FUtil actualPoint:pos Size:s]];
      [l addChild:sp];
    }else if([name compare:@"button"] == NSOrderedSame){
      FButton *b = [FUtil buttonFromXmlElement:element];
      [l addChild:b];
    }
    element = element->nextSibling;
  }
  return l;
}

+(NSMutableDictionary*)getDictFromAttribute:(TBXMLElement*)element{
  NSMutableDictionary *pars = [NSMutableDictionary dictionary];
  TBXMLAttribute* attr = element->firstAttribute;
  for(;attr!=nil;){
    NSString *name = [TBXML attributeName:attr];
    NSString *value = [TBXML attributeValue:attr];
    //NSLog(@"%@ %@", name, value);
    [pars setObject:value forKey:name];
    attr = attr->next;
  }
  return pars;
}

+(NSString*)expandStr:(NSString*)str WithDict:(NSMutableDictionary*)dict{
  NSMutableString *mstr = [NSMutableString stringWithString:str];
  //int size = mstr.length;
  int p = 0;
  //NSLog(@"%@ %d", mstr, mstr.length);
  for(; p<mstr.length;){
    NSRange limit;
    limit.location = p;
    limit.length = mstr.length-p;
    //NSRange res1 = [mstr rangeOfString:@"{{"];
    NSRange res1 = [mstr rangeOfString:@"{{" options:1 range:limit];
    //NSLog(@"res1 %d %d", res1.location, res1.length);
    if(res1.length == 0){
      //NSLog(@"break res1 %d %d", res1.location, res1.length);
      break;
    }
    limit.location = res1.location+2;
    limit.length = mstr.length-(res1.location+2);
    NSRange res2 = [mstr rangeOfString:@"}}" options:1 range:limit];
    //NSLog(@"res2 %d %d", res2.location, res2.length);
    p = res2.location+2;
    
    NSRange dst;
    dst.location = res1.location;
    dst.length = res2.location - res1.location + 2;
    //NSLog(@"dst %d %d", dst.location, dst.length);
    
    NSString *key = [mstr substringWithRange:dst];
    //NSLog(@"%@", key);
    NSRange tmp;
    tmp.location = 2;
    tmp.length = key.length - 4;
    key = [key substringWithRange:tmp];
    //NSLog(@"%@", key);
    
    NSString *v = [dict objectForKey:key];
    if(!v){
      v = @"";
    }
    //NSLog(@"value %@ %@ %d", key, v, v.length);
    //NSLog(@"begin replace %d", mstr.length);
    [mstr replaceCharactersInRange:dst withString:v];
    //NSLog(@"end replace %d", mstr.length);
    p += (v.length-dst.length);
    //NSLog(@"positon %d", p);
  }
  //NSLog(@"%@ %d", mstr, mstr.length);
  return mstr;
}

@end
